gl path "~/Dropbox/voter_id/Replication"

cap log close
log using "$path/table_a7.log", replace

use "$path/nc_dataset.dta" if new_reg == 0, clear

// drop 2018 
drop if inlist(election, 11, 12)

drop new_reg noid_p_2016 dem rep

sort id election

replace voted = 0 if voted == .

// replace voted with NA if under 18 / ineligible in that election year 
drop if birth_year > 1998 & birth_year < 9999
replace voted = . if (birth_year > 1990 & birth_year < 9999) & (election == 1 | election == 2) // 2008
replace voted = . if (birth_year > 1992 & birth_year < 9999) & (election == 3 | election == 4) // 2010
replace voted = . if (birth_year > 1994 & birth_year < 9999) & (election == 5 | election == 6) // 2012
replace voted = . if (birth_year > 1996 & birth_year < 9999) & (election == 7 | election == 8) // 2014

** create string encoding of possible pre-treatment outcome paths
tostring voted, generate(outcome_path)

by id: gen outcome_path_pretreat = outcome_path[1] + outcome_path[2] + ///
								outcome_path[3] + outcome_path[4] + ///
								outcome_path[5] + outcome_path[6] + ///
								outcome_path[7] + outcome_path[8]

gen count = 1

// keep primaries only
keep if mod(election,2) == 1

// generate race interactions
replace black = 0 if black == .
replace hispanic = 0 if hispanic == .
replace othernw = 0 if othernw == .
gen treat_black = treat * black
gen treat_hispanic = treat * hispanic 
gen treat_othernw = treat * othernw
gen no_dmv_black = no_dmv_match * black 
gen no_dmv_hispanic = no_dmv_match * hispanic
gen no_dmv_othernw = no_dmv_match * othernw

replace voted = 0 if voted == .

// construct age bins, give young voters who are ineligible for some election their own age bin
gen age_bin = 11 if (birth_year > 1990 & birth_year < 9999)
replace age_bin = 12 if (birth_year > 1992 & birth_year < 9999)
replace age_bin = 13 if (birth_year > 1994 & birth_year < 9999)
replace age_bin = 14 if (birth_year > 1996 & birth_year < 9999)
// give those who are eligible over the whole period their own age decile
xtile age_decile = birth_year if (birth_year <= 1990), nq(10)
replace age_bin = age_decile if (birth_year <= 1990)
drop age_decile

compress

sort id election

* vanilla diff in diff

reghdfe voted treat treat_black treat_hispanic treat_othernw, a(id election) cluster(id)
local b1 = _b[treat]
local se1 = _se[treat]
local b1_2 = _b[treat_black]
local se1_2 = _se[treat_black]
local b1_3 = _b[treat_hispanic]
local se1_3 = _se[treat_hispanic]
local b1_4 = _b[treat_othernw]
local se1_4 = _se[treat_othernw]
local n1 = e(N)
local nclust1 = e(N_clust)

* race by year
reghdfe voted treat treat_black treat_hispanic treat_othernw, a(id race_by_year) cluster(id)
local b2 = _b[treat]
local se2 = _se[treat]
local b2_2 = _b[treat_black]
local se2_2 = _se[treat_black]
local b2_3 = _b[treat_hispanic]
local se2_3 = _se[treat_hispanic]
local b2_4 = _b[treat_othernw]
local se2_4 = _se[treat_othernw]
local n2 = e(N)
local nclust2 = e(N_clust)

* age by year 
reghdfe voted treat treat_black treat_hispanic treat_othernw, a(id age_by_year) cluster(id)
local b3 = _b[treat]
local se3 = _se[treat]
local b3_2 = _b[treat_black]
local se3_2 = _se[treat_black]
local b3_3 = _b[treat_hispanic]
local se3_3 = _se[treat_hispanic]
local b3_4 = _b[treat_othernw]
local se3_4 = _se[treat_othernw]
local n3 = e(N)
local nclust3 = e(N_clust)

* age by race by year
reghdfe voted treat treat_black treat_hispanic treat_othernw, a(id race_by_age_by_year) cluster(id)
local b4 = _b[treat]
local se4 = _se[treat]
local b4_2 = _b[treat_black]
local se4_2 = _se[treat_black]
local b4_3 = _b[treat_hispanic]
local se4_3 = _se[treat_hispanic]
local b4_4 = _b[treat_othernw]
local se4_4 = _se[treat_othernw]
local n4 = e(N)
local nclust4 = e(N_clust)



preserve

collapse (sum) count (mean) voted, by(outcome_path_pretreat no_dmv_match no_dmv_black no_dmv_hispanic no_dmv_othernw election)

*** get N by path by summing together n treated and n control
sort outcome_path no_dmv_match no_dmv_black no_dmv_hispanic no_dmv_othernw election
// get treated units in each bin
gen tot_tmp = count if no_dmv_match & ///
	((no_dmv_match != no_dmv_match[_n-1]) | ///
	(no_dmv_black != no_dmv_black[_n-1]) | ///
	(no_dmv_hispanic != no_dmv_hispanic[_n-1]) | ///
	(no_dmv_othernw != no_dmv_othernw[_n-1]))
// get treated units in outcome path
egen tot_treat = sum(tot_tmp), by(outcome_path)
// get control units in each outcome path
by outcome_path no_dmv_match no_dmv_black no_dmv_hispanic no_dmv_othernw: replace tot_tmp = count[1] if _n == 1
// get total units in each outcome path
egen tot = sum(tot_tmp), by(outcome_path)
// N_voters is the number of voters who enter into the regression
egen N_voters = sum(tot_tmp)
// get number of elections
unique election
// N is number of voters * number of elections
gen long N = N_voters * r(unique)
drop tot_tmp
gen tot_control = tot - tot_treat

*** get weights for fw based on total n per stratum
*** each stratum has 10 obs
*** fw requires integers so need to round
gen tot2 = round(tot/10)
gen tot_treat2 = round(tot_treat/10)
egen op = group(outcome_path)


reghdfe voted no_dmv_match no_dmv_black no_dmv_hispanic no_dmv_othernw [fw=tot_treat2], a(op election)
local b5 = _b[no_dmv_match]
local se5 = _se[no_dmv_match]
local b5_2 = _b[no_dmv_black]
local se5_2 = _se[no_dmv_black]
local b5_3 = _b[no_dmv_hispanic]
local se5_3 = _se[no_dmv_hispanic]
local b5_4 = _b[no_dmv_othernw]
local se5_4 = _se[no_dmv_othernw]
local n5 = N
local nclust5 = N_voters


* match on pre-treatment turnout path and race

restore
preserve

collapse (sum) count (mean) voted, by(outcome_path_pretreat no_dmv_match no_dmv_black no_dmv_hispanic no_dmv_othernw race_string election)

*** get N by path by summing together n treated and n control
sort outcome_path no_dmv_match race_string no_dmv_black no_dmv_hispanic no_dmv_othernw election
// get treated units in each bin
gen tot_tmp = count if no_dmv_match & ///
	((no_dmv_match != no_dmv_match[_n-1]) | ///
	(no_dmv_black != no_dmv_black[_n-1]) | ///
	(no_dmv_hispanic != no_dmv_hispanic[_n-1]) | ///
	(no_dmv_othernw != no_dmv_othernw[_n-1]))
// get treated units in outcome path and race
egen tot_treat = sum(tot_tmp), by(outcome_path race_string)
// get control units in each outcome path by race
by outcome_path no_dmv_match race_string no_dmv_black no_dmv_hispanic no_dmv_othernw: replace tot_tmp = count[1] if _n == 1
// get total units in each outcome path
egen tot = sum(tot_tmp), by(outcome_path race_string)
// N_voters is the number of voters who enter into the regression
egen N_voters = sum(tot_tmp)
// get number of elections
unique election
// N is number of voters * number of elections
gen long N = N_voters * r(unique)
drop tot_tmp
gen tot_control = tot - tot_treat

*** get weights for fw based on total n per stratum
*** each stratum has 10 obs
*** fw requires integers so need to round
gen tot2 = round(tot/10)
gen tot_treat2 = round(tot_treat/10)
egen op = group(outcome_path race_string)


reghdfe voted no_dmv_match no_dmv_black no_dmv_hispanic no_dmv_othernw [fw=tot_treat2], a(op election)
local b6 = _b[no_dmv_match]
local se6 = _se[no_dmv_match]
local b6_2 = _b[no_dmv_black]
local se6_2 = _se[no_dmv_black]
local b6_3 = _b[no_dmv_hispanic]
local se6_3 = _se[no_dmv_hispanic]
local b6_4 = _b[no_dmv_othernw]
local se6_4 = _se[no_dmv_othernw]
local n6 = N 
local nclust6 = N_voters

restore


collapse (sum) count (mean) voted, ///
	by(outcome_path_pretreat no_dmv_match no_dmv_black no_dmv_hispanic no_dmv_othernw race_string age_bin election)

drop if age_bin == . 

*** get N by path by summing together n treated and n control
sort outcome_path no_dmv_match race_string age_bin no_dmv_black no_dmv_hispanic no_dmv_othernw election
// get treated units in each bin
gen tot_tmp = count if no_dmv_match & ///
	((no_dmv_match != no_dmv_match[_n-1]) | ///
	(no_dmv_black != no_dmv_black[_n-1]) | ///
	(no_dmv_hispanic != no_dmv_hispanic[_n-1]) | ///
	(no_dmv_othernw != no_dmv_othernw[_n-1]) | ///
	(age_bin != age_bin[_n-1]))
// get treated units in outcome path and race and age bin
egen tot_treat = sum(tot_tmp), by(outcome_path race_string age_bin)
// get control units in each outcome path by race and age_bin
by outcome_path no_dmv_match race_string age_bin no_dmv_black no_dmv_hispanic no_dmv_othernw: replace tot_tmp = count[1] if _n == 1
// get total units in each outcome path race and age bin
egen tot = sum(tot_tmp), by(outcome_path race_string age_bin)
// N_voters is the number of voters who enter into the regression
egen N_voters = sum(tot_tmp)
// get number of elections
unique election
// N is number of voters * number of elections
gen long N = N_voters * r(unique)
drop tot_tmp
gen tot_control = tot - tot_treat

*** get weights for fw based on total n per stratum
*** each stratum has 10 obs
*** fw requires integers so need to round
gen tot2 = round(tot/10)
gen tot_treat2 = round(tot_treat/10)
egen op = group(outcome_path race_string age_bin)

reghdfe voted no_dmv_match no_dmv_black no_dmv_hispanic no_dmv_othernw [fw=tot_treat2], a(op election)
local b7 = _b[no_dmv_match]
local se7 = _se[no_dmv_match]
local b7_2 = _b[no_dmv_black]
local se7_2 = _se[no_dmv_black]
local b7_3 = _b[no_dmv_hispanic]
local se7_3 = _se[no_dmv_hispanic]
local b7_4 = _b[no_dmv_othernw]
local se7_4 = _se[no_dmv_othernw]
local n7 = N 
local nclust7 = N_voters

log close

quietly {
	cap log close
	set linesize 255
	log using "$path/table_a7.tex", text replace
	
	noisily dis "\begin{table}[t]"
	noisily dis "\centering"
	noisily dis "\caption{\textbf{Effect of Voter ID Law on Primary Election Turnout Among Those Without ID, Individual Level, 2008--2016.}"
	noisily dis "\label{tab:diff_in_diff_p_race}}"
	noisily dis "\resizebox{\textwidth}{!} {"
	noisily dis "\begin{tabular}{lccccccc}"
	noisily dis "\toprule \toprule"
	noisily dis " & \multicolumn{7}{c}{Voted in Primary (0-1)}\\"
	noisily dis " & (1) & (2) & (3) & (4) & (5) & (6) & (7) \\"
	noisily dis "\midrule"
	noisily dis "No DMV * 2016 & " %4.3f `b1' " & " %4.3f `b2' " & " %4.3f `b3' " & " %4.3f `b4' " & " %4.3f `b5' " & " %4.3f `b6' " & " %4.3f `b7'  "\\"
	noisily dis " & (" %4.3f `se1' ") & (" %4.3f `se2' ") & (" %4.3f `se3' ") & (" %4.3f `se4' ") & (" %4.3f `se5' ") & (" %4.3f `se6' ") & (" %4.3f `se7' ") \smallskip\\"
	noisily dis "No DMV * 2016 * Black & " %4.3f `b1_2' " & " %4.3f `b2_2' " & " %4.3f `b3_2' " & " %4.3f `b4_2' " & " %4.3f `b5_2' " & " %4.3f `b6_2' " & " %4.3f `b7_2'   "\\"
	noisily dis " & (" %4.3f `se1_2' ") & (" %4.3f `se2_2' ") & (" %4.3f `se3_2' ") & (" %4.3f `se4_2' ") & (" %4.3f `se5_2' ") & (" %4.3f `se6_2' ") & (" %4.3f `se7_2' ")  \smallskip\\"
	noisily dis "No DMV * 2016 * Hispanic & " %4.3f `b1_3' " & " %4.3f `b2_3' " & " %4.3f `b3_3' " & " %4.3f `b4_3' " & " %4.3f `b5_3' " & " %4.3f `b6_3' " & " %4.3f `b7_3'  "\\"
	noisily dis " & (" %4.3f `se1_3' ") & (" %4.3f `se2_3' ") & (" %4.3f `se3_3' ") & (" %4.3f `se4_3' ") & (" %4.3f `se5_3' ") & (" %4.3f `se6_3' ") & (" %4.3f `se7_3' ") \smallskip\\"
	noisily dis "No DMV * 2016 * Other NW & " %4.3f `b1_4' " & " %4.3f `b2_4' " & " %4.3f `b3_4' " & " %4.3f `b4_4' " & " %4.3f `b5_4' " & " %4.3f `b6_4' " & " %4.3f `b7_4'  "\\"
	noisily dis " & (" %4.3f `se1_4' ") & (" %4.3f `se2_4' ") & (" %4.3f `se3_4' ") & (" %4.3f `se4_4' ") & (" %4.3f `se5_4' ") & (" %4.3f `se6_4' ") & (" %4.3f `se7_4' ") \smallskip\\"

	noisily dis " N & " %12.0fc `n1' " & " %12.0fc `n2' " & " %12.0fc `n3' " & " %12.0fc `n4' " & " %12.0fc `n5' " & " %12.0fc `n6' " & " %12.0fc `n7' " \\ "
	noisily dis " \# Voters & "  %12.0fc `nclust1' " & " %12.0fc `nclust2' " & " %12.0fc `nclust3' " & " %12.0fc `nclust4' " & " %12.0fc `nclust5' " & " %12.0fc `nclust6' " & " %12.0fc `nclust7' " \\ "
	
	noisily dis "Individual FEs & Y & Y & Y & Y & N & N & N \\"
	noisily dis "Year FEs & Y & N & N & N & Y & Y & Y  \\"
	noisily dis "Race by Year FEs & N & Y & N & N & N & N & N  \\"
	noisily dis "Age by Year FEs & N & N & Y & N & N & N & N \\"
	noisily dis "Race by Age by Year FEs & N & N & N & Y & N & N & N \\"
	noisily dis "Exact Match on Turnout & N & N & N & N & Y & Y & Y \\"
	noisily dis "Exact Match on Race & N & N & N & N & N & Y & Y \\"
	noisily dis "Exact Match on Age Bin & N & N & N & N & N & N & Y \\"

	noisily dis "\bottomrule \bottomrule"
	noisily dis "\multicolumn{8}{p{1.15\textwidth}}{\footnotesize Robust standard errors clustered by individual in parentheses.  Main effects for No DMV Match and 2016 are absorbed by fixed effects.  "
	noisily dis "Exact matching on turnout matches units based on all primary and general elections from 2008-2014.  For exact matching on age, we construct a separate age bin for "
	noisily dis "each group of voters who were under 18 for a given set of elections, so the cohort of voters who became newly eligible to participate in 2010, 2012, 2014, and 2016 each have their own age bin.  "
	noisily dis "For voters who were eligible for all elections since 2008, we construct age deciles.}"

	noisily dis "\end{tabular}}"
	noisily dis "\end{table}"
	
	log off
	
}





